package com.virtualperson.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.virtualperson.dto.ChatRequest;
import com.virtualperson.dto.ChatResponse;
import com.virtualperson.service.AliyunAIService;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@Controller
@RequestMapping("/api/ai")
@RequiredArgsConstructor
@Tag(name = "AI聊天服务", description = "提供基于阿里云通义千问的智能对话服务")
public class AIController {

    private final AliyunAIService aliyunAIService;
    private final ObjectMapper objectMapper;
    private final ExecutorService sseExecutor = Executors.newCachedThreadPool();

    @Operation(
        summary = "AI聊天页面",
        description = "返回AI聊天的前端页面"
    )
    @GetMapping("/page")
    public String aiChatPage() {
        return "ai-chat";
    }

    @Operation(
        summary = "AI聊天测试页面",
        description = "返回AI聊天测试的前端页面"
    )
    @GetMapping("/test-page")
    public String aiChatTestPage() {
        return "test_ai_chat";
    }

    @Operation(
        summary = "AI聊天简单测试",
        description = "返回简单的测试页面"
    )
    @GetMapping("/simple-test")
    public String simpleTestPage() {
        return "simple_test";
    }

    @Operation(
        summary = "AI聊天",
        description = "与AI进行对话，支持多轮对话和参数调节"
    )
    @ApiResponses(value = {
        @ApiResponse(
            responseCode = "200",
            description = "聊天成功",
            content = @Content(mediaType = "application/json",
                schema = @Schema(implementation = ChatResponse.class))
        ),
        @ApiResponse(
            responseCode = "400",
            description = "请求参数错误",
            content = @Content(mediaType = "application/json")
        ),
        @ApiResponse(
            responseCode = "500",
            description = "服务器内部错误",
            content = @Content(mediaType = "application/json")
        )
    })
    @PostMapping("/chat")
    @ResponseBody
    public ChatResponse chat(
        @Parameter(description = "聊天请求参数", required = true)
        @RequestBody ChatRequest request
    ) {
        log.info("收到AI聊天请求: {}", request);
        
        // 同步模式：一次性返回完整结果
        if (!Boolean.TRUE.equals(request.getStreamMode())) {
            return aliyunAIService.chat(request);
        } else {
            // 流式模式：返回错误提示，建议使用流式接口
            ChatResponse response = new ChatResponse();
            response.setSuccess(false);
            response.setErrorMessage("请使用 /api/ai/chat/stream 接口进行流式聊天");
            return response;
        }
    }

    @Operation(
        summary = "AI流式聊天",
        description = "与AI进行流式对话，实时返回AI回复内容"
    )
    @ApiResponses(value = {
        @ApiResponse(
            responseCode = "200",
            description = "流式聊天成功",
            content = @Content(mediaType = "text/event-stream")
        ),
        @ApiResponse(
            responseCode = "400",
            description = "请求参数错误"
        ),
        @ApiResponse(
            responseCode = "500",
            description = "服务器内部错误"
        )
    })
    @PostMapping(value = "/chat/stream")
    public SseEmitter chatStream(
        @Parameter(description = "聊天请求参数", required = true)
        @RequestBody ChatRequest request
    ) {
        log.info("收到AI流式聊天请求: {}", request);
        
        SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
        
        // 添加连接建立日志
        log.info("SSE连接已建立，emitter: {}", emitter);

        sseExecutor.execute(() -> {
            try {
                log.info("开始执行流式聊天任务");
                
                aliyunAIService.chatStream(request, new AliyunAIService.StreamCallback() {
                    @Override
                    public void onText(String text) {
                        try {
                            log.info("准备发送文本片段: {}", text);
                            
                            // 发送标准SSE格式 - 直接发送字符串
                            String eventData = String.format("event: text\ndata: {\"text\":\"%s\"}\n\n", 
                                text.replace("\"", "\\\"").replace("\n", "\\n"));
                            
                            log.info("发送SSE数据: {}", eventData);
                            emitter.send(eventData, MediaType.TEXT_EVENT_STREAM);
                            
                            log.info("SSE文本事件发送成功");
                        } catch (IOException e) {
                            log.error("发送SSE文本失败", e);
                            emitter.completeWithError(e);
                        }
                    }
                    
                    @Override
                    public void onComplete(String fullText) {
                        try {
                            log.info("准备发送完成事件，完整文本: {}", fullText);
                            
                            // 发送完成事件 - 直接发送字符串
                            String eventData = "event: complete\ndata: {\"text\":\"对话完成\"}\n\n";
                            emitter.send(eventData, MediaType.TEXT_EVENT_STREAM);
                            
                            log.info("SSE完成事件发送成功");
                            emitter.complete();
                        } catch (IOException e) {
                            log.error("发送SSE完成事件失败", e);
                            emitter.completeWithError(e);
                        }
                    }
                    
                    @Override
                    public void onError(String error) {
                        try {
                            log.error("准备发送错误事件: {}", error);
                            
                            // 发送错误事件 - 直接发送字符串
                            String eventData = String.format("event: error\ndata: {\"text\":\"%s\"}\n\n", 
                                error.replace("\"", "\\\"").replace("\n", "\\n"));
                            emitter.send(eventData, MediaType.TEXT_EVENT_STREAM);
                            
                            log.error("SSE错误事件发送成功");
                            emitter.complete();
                        } catch (IOException e) {
                            log.error("发送SSE错误事件失败", e);
                        }
                        emitter.completeWithError(new RuntimeException(error));
                    }
                });
            } catch (Exception e) {
                log.error("流式聊天服务执行失败", e);
                emitter.completeWithError(e);
            }
        });
        
        return emitter;
    }

    @Operation(
        summary = "测试阿里云API配置",
        description = "验证阿里云API密钥和配置是否正确"
    )
    @GetMapping(value = "/test-aliyun-config")
    @ResponseBody
    public String testAliyunConfig() {
        log.info("收到阿里云配置测试请求");
        
        try {
            // 测试简单的同步调用
            String prompt = "你好";
            List<Message> messages = new ArrayList<>();
            messages.add(Message.builder()
                    .role(Role.USER.getValue())
                    .content(prompt)
                    .build());
            
            GenerationParam param = GenerationParam.builder()
                    .model("qwen-turbo")
                    .messages(messages)
                    .temperature(0.7f)
                    .maxTokens(100)
                    .apiKey(aliyunAIService.getAliyunConfig().getApiKey())
                    .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                    .build();
            
            log.info("测试参数: model={}, apiKey={}", param.getModel(), 
                param.getApiKey() != null ? "已设置" : "未设置");
            
            Generation gen = new Generation();
            GenerationResult result = gen.call(param);
            
            log.info("测试调用成功，结果: {}", result);
            
            return "阿里云API配置正确！测试响应: " + result.getOutput().getText();
            
        } catch (Exception e) {
            log.error("阿里云API配置测试失败", e);
            return "阿里云API配置测试失败: " + e.getMessage();
        }
    }

    @Operation(
        summary = "基本HTTP测试",
        description = "测试基本的HTTP连接是否正常"
    )
    @GetMapping(value = "/basic-test")
    @ResponseBody
    public String basicTest() {
        log.info("收到基本HTTP测试请求");
        return "HTTP连接正常！当前时间：" + System.currentTimeMillis();
    }

    @Operation(
        summary = "最简单的SSE测试",
        description = "最基本的SSE连接测试"
    )
    @GetMapping(value = "/simple-sse-test")
    public SseEmitter simpleSseTest() {
        log.info("收到最简单的SSE测试请求");
        
        SseEmitter emitter = new SseEmitter();
        
        sseExecutor.execute(() -> {
            try {
                log.info("开始最简单的SSE测试");
                
                // 发送一个简单的消息
                String message = "data: {\"message\":\"Hello SSE!\"}\n\n";
                log.info("发送SSE消息: {}", message);
                emitter.send(message, MediaType.TEXT_EVENT_STREAM);
                
                Thread.sleep(1000);
                
                // 发送第二个消息
                String message2 = "data: {\"message\":\"Second message!\"}\n\n";
                log.info("发送第二个SSE消息: {}", message2);
                emitter.send(message2, MediaType.TEXT_EVENT_STREAM);
                
                Thread.sleep(1000);
                
                // 完成
                log.info("SSE测试完成");
                emitter.complete();
                
            } catch (Exception e) {
                log.error("SSE测试失败", e);
                emitter.completeWithError(e);
            }
        });
        
        return emitter;
    }

    @Operation(
        summary = "测试流式响应",
        description = "简单的流式响应测试，用于验证SSE格式"
    )
    @GetMapping(value = "/test-stream")
    public SseEmitter testStream() {
        log.info("收到测试流式请求");
        
        SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
        
        sseExecutor.execute(() -> {
            try {
                log.info("开始测试流式响应");
                
                // 模拟流式文本
                String[] texts = {"你好", "，", "这是", "一个", "测试", "流式", "响应", "。"};
                
                for (int i = 0; i < texts.length; i++) {
                    Thread.sleep(500); // 延迟500ms
                    
                    String text = texts[i];
                    String eventData = String.format("event: text\ndata: {\"text\":\"%s\"}\n\n", text);
                    
                    log.info("发送测试文本: {}", text);
                    emitter.send(eventData, MediaType.TEXT_EVENT_STREAM);
                }
                
                // 发送完成事件
                String completeData = "event: complete\ndata: {\"text\":\"测试完成\"}\n\n";
                emitter.send(completeData, MediaType.TEXT_EVENT_STREAM);
                
                log.info("测试流式响应完成");
                emitter.complete();
                
            } catch (Exception e) {
                log.error("测试流式响应失败", e);
                emitter.completeWithError(e);
            }
        });
        
        return emitter;
    }
} 